package com.wzh.navcode.interceptor;

import com.wzh.navcode.annotention.PreventDirectAccess;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author wangzhenghai
 */
@Configuration
@Order(-1)
public class RequestSourceInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 检查是否是HandlerMethod
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            // 检查是否有PreventDirectAccess注解
            PreventDirectAccess preventDirectAccess = handlerMethod.getMethodAnnotation(PreventDirectAccess.class);
            // 如果有注解，则进行检查
            if (preventDirectAccess != null) {
                // 获取请求头信息
                String referer = request.getHeader("Referer");
                String xRequestedWith = request.getHeader("X-Requested-With");
                String userAgent = request.getHeader("User-Agent");
                // 检查是否是AJAX请求或来自允许的页面
                boolean isAjax = "XMLHttpRequest".equals(xRequestedWith);
                boolean hasValidReferer = StringUtils.isNotEmpty(referer) && StringUtils.isNotEmpty(userAgent) && (
                        referer.contains("localhost") ||
                                referer.contains("wangzh.work")
                );
                if (!isAjax && !hasValidReferer) {
                    response.setContentType("application/json;charset=UTF-8");
                    response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                    response.getWriter().write("{\"code\":403,\"message\":\"非法访问\"}");
                    return false;
                }
            }
        }
        return true;
    }
}